﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.DataSourcesRaster;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geoprocessor;
using ESRI.ArcGIS.SpatialAnalystTools;
using System.Runtime.InteropServices;
using System.IO;

namespace School
{
    public partial class ReclassifyForm : Form
    {
        // 显式声明 map 字段
        private IMap map;

        public ReclassifyForm(IMap currentMap)
        {
            InitializeComponent();
            map = currentMap;
        }

        private void btnBrowseInput_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                openFileDialog.Filter = "栅格文件 (*.tif;*.img;*.jpg;*.png)|*.tif;*.img;*.jpg;*.png|所有文件 (*.*)|*.*";
                openFileDialog.Title = "选择栅格文件";

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    txtInputRaster.Text = openFileDialog.FileName;
                }
            }
        }

        private void btnBrowseOutput_Click(object sender, EventArgs e)
        {
            using (SaveFileDialog saveFileDialog = new SaveFileDialog())
            {
                saveFileDialog.Filter = "栅格文件 (*.tif)|*.tif|所有文件 (*.*)|*.*";
                saveFileDialog.Title = "保存栅格文件";

                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    txtOutputRaster.Text = saveFileDialog.FileName;
                }
            }
        }

        private void btnExecute_Click(object sender, EventArgs e)
        {
            Geoprocessor gp = new Geoprocessor();
            gp.OverwriteOutput = true;

            try
            {
                if (string.IsNullOrEmpty(txtInputRaster.Text) || !File.Exists(txtInputRaster.Text))
                {
                    MessageBox.Show("请选择有效的输入栅格文件", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (string.IsNullOrEmpty(txtOutputRaster.Text))
                {
                    MessageBox.Show("请指定输出栅格文件", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (cmbReclassifyMethod.SelectedIndex < 0)
                {
                    MessageBox.Show("请选择重分类方法", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                switch (cmbReclassifyMethod.SelectedIndex)
                {
                    case 0: // 等间隔分类
                        ExecuteEqualIntervalReclassify(gp);
                        break;
                    case 1: // 等间隔分类并取反
                        ExecuteInvertedEqualIntervalReclassify(gp);
                        break;
                    case 2: // 0值去除
                        ExecuteZeroToNoDataReclassify(gp);
                        break;
                }

                MessageBox.Show("重分类完成！", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                AddRasterToMap(txtOutputRaster.Text);
            }
            catch (Exception ex)
            {
                StringBuilder errorMsg = new StringBuilder();
                errorMsg.AppendLine("执行重分类时出错: " + ex.Message);

                if (gp.MessageCount > 0)
                {
                    for (int i = 0; i < gp.MessageCount; i++)
                    {
                        errorMsg.AppendLine($"错误 {i + 1}: {gp.GetMessage(i)}");
                    }
                }

                MessageBox.Show(errorMsg.ToString(), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void ExecuteEqualIntervalReclassify(Geoprocessor gp)
        {
            IRasterDataset rasterDataset = null;
            try
            {
                // 打开栅格数据集
                IWorkspaceFactory workspaceFactory = new RasterWorkspaceFactoryClass();
                string directory = Path.GetDirectoryName(txtInputRaster.Text);
                string fileName = Path.GetFileName(txtInputRaster.Text);

                IRasterWorkspace rasterWorkspace = (IRasterWorkspace)workspaceFactory.OpenFromFile(directory, 0);
                rasterDataset = rasterWorkspace.OpenRasterDataset(fileName);

                // 获取栅格波段
                IRasterBandCollection bandCollection = (IRasterBandCollection)rasterDataset;
                IRasterBand rasterBand = bandCollection.Item(0);

                // 直接强制计算统计信息（不使用 HasStatistics）
                rasterBand.ComputeStatsAndHist();

                // 获取统计信息
                IRasterStatistics rasterStats = rasterBand.Statistics;
                double min = rasterStats.Minimum;
                double max = rasterStats.Maximum;
                double interval = (max - min) / 10;

                // 构建重分类规则
                StringBuilder remapTable = new StringBuilder();
                for (int i = 0; i < 10; i++)
                {
                    double start = min + i * interval;
                    double end = (i == 9) ? max : start + interval;
                    int newValue = i + 1;

                    remapTable.Append($"{start} {end} {newValue}");
                    if (i < 9) remapTable.Append(";");
                }

                // 执行重分类
                Reclassify reclassify = new Reclassify();
                reclassify.in_raster = txtInputRaster.Text;
                reclassify.out_raster = txtOutputRaster.Text;
                reclassify.reclass_field = "VALUE";
                reclassify.remap = remapTable.ToString();

                gp.Execute(reclassify, null);
            }
            catch (Exception ex)
            {
                throw new Exception($"等间隔分类失败: {ex.Message}");
            }
            finally
            {
                if (rasterDataset != null)
                    Marshal.FinalReleaseComObject(rasterDataset);
            }
        }

        private void ExecuteInvertedEqualIntervalReclassify(Geoprocessor gp)
        {
            IRasterDataset rasterDataset = null;
            try
            {
                // 打开栅格数据集
                IWorkspaceFactory workspaceFactory = new RasterWorkspaceFactoryClass();
                string directory = Path.GetDirectoryName(txtInputRaster.Text);
                string fileName = Path.GetFileName(txtInputRaster.Text);

                IRasterWorkspace rasterWorkspace = (IRasterWorkspace)workspaceFactory.OpenFromFile(directory, 0);
                rasterDataset = rasterWorkspace.OpenRasterDataset(fileName);

                // 获取栅格波段
                IRasterBandCollection bandCollection = (IRasterBandCollection)rasterDataset;
                IRasterBand rasterBand = bandCollection.Item(0);

                // 直接强制计算统计信息（不使用 HasStatistics）
                rasterBand.ComputeStatsAndHist();

                // 获取统计信息
                IRasterStatistics rasterStats = rasterBand.Statistics;
                double min = rasterStats.Minimum;
                double max = rasterStats.Maximum;
                double interval = (max - min) / 10;

                // 构建重分类规则（取反赋值）
                StringBuilder remapTable = new StringBuilder();
                for (int i = 0; i < 10; i++)
                {
                    double start = min + i * interval;
                    double end = (i == 9) ? max : start + interval;
                    int newValue = 10 - i;

                    remapTable.Append($"{start} {end} {newValue}");
                    if (i < 9) remapTable.Append(";");
                }

                // 执行重分类
                Reclassify reclassify = new Reclassify();
                reclassify.in_raster = txtInputRaster.Text;
                reclassify.out_raster = txtOutputRaster.Text;
                reclassify.reclass_field = "VALUE";
                reclassify.remap = remapTable.ToString();

                gp.Execute(reclassify, null);
            }
            catch (Exception ex)
            {
                throw new Exception($"反向等间隔分类失败: {ex.Message}");
            }
            finally
            {
                if (rasterDataset != null)
                    Marshal.FinalReleaseComObject(rasterDataset);
            }
        }

        private void ExecuteZeroToNoDataReclassify(Geoprocessor gp)
        {
            try
            {
                // 修正的重映射参数格式
                string remapRule = "0 NODATA";

                Reclassify reclassify = new Reclassify();
                reclassify.in_raster = txtInputRaster.Text;
                reclassify.out_raster = txtOutputRaster.Text;
                reclassify.reclass_field = "VALUE";
                reclassify.remap = remapRule;  // 使用修正后的格式

                gp.Execute(reclassify, null);
            }
            catch (Exception ex)
            {
                throw new Exception($"0值转NoData失败: {ex.Message}");
            }
        }

        private void AddRasterToMap(string rasterPath)
        {
            try
            {
                IRasterLayer rasterLayer = new RasterLayerClass();
                rasterLayer.CreateFromFilePath(rasterPath);
                rasterLayer.Name = Path.GetFileNameWithoutExtension(rasterPath);

                // 使用显式声明的 map 字段
                map.AddLayer(rasterLayer as ILayer);

                IActiveView activeView = map as IActiveView;
                activeView.Refresh();
            }
            catch (Exception ex)
            {
                MessageBox.Show("无法将结果添加到地图: " + ex.Message, "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}